'''
Author: Sjy
Description: 数组list 带有增删功能 允许编辑 注意只有两列 一列数值 一列操作
'''
# -*- coding: utf-8 -*-

from PyQt5 import  QtWidgets, QtCore, QtGui

import gui.components.ui_custom_table as ui_custom_table

CustomCellStr = ui_custom_table.CustomCellStr
CustomCellLabel = ui_custom_table.CustomCellLabel
CustomCellInt = ui_custom_table.CustomCellInt
CustomCellFloat = ui_custom_table.CustomCellFloat
CustomCellBool = ui_custom_table.CustomCellBool
CustomCellCheckbox = ui_custom_table.CustomCellCheckbox
CustomLabelInt = ui_custom_table.CustomLabelInt
createLayout = ui_custom_table.createLayout


# 自定义工具盒子
class CustomCellToolbar(QtWidgets.QWidget):
    def __init__(self, parent, *args, **kwargs):
        super(CustomCellToolbar, self).__init__(*args, **kwargs)
        self.table = parent
        self.data = {}
        layout = createLayout()
        self.btnAdd = QtWidgets.QPushButton('')
        self.btnAdd.setIcon(QtGui.QIcon('icons/add_circle.png'))
        self.btnAdd.setIconSize(QtCore.QSize(20, 20))
        self.btnAdd.clicked.connect(lambda *args, **kwargs: parent._addRowHandle(self))

        self.btnDel = QtWidgets.QPushButton('')
        self.btnDel.setIconSize(QtCore.QSize(20, 20))
        self.btnDel.setIcon(QtGui.QIcon('icons/remove_circle.png'))
        self.btnDel.clicked.connect(lambda *args, **kwargs: parent._delRowHandle(self))

        layout.addWidget(self.btnAdd)
        layout.addWidget(self.btnDel)
        self.setLayout(layout)

# 此组件初始时必须有一行两列
class Ui_tableEditedDataList(QtWidgets.QTableWidget):
    col_value = 0
    col_button = 1

    TYPES = {
        'text': CustomCellStr,
        'label': CustomCellLabel,
        'labelInt':CustomLabelInt,
        'str': CustomCellStr,
        'int':CustomCellInt,
        'float':CustomCellFloat,
        'bool': CustomCellBool,
        'checkbox': CustomCellCheckbox,
    }
    def __init__(self, params:dict={}, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__valueWidget = None
        self._initTableStyle()
        self._initValueTypeWidget(params.get('valueType', 'text'))
        self._initHeaders()
        
    def _initTableStyle(self):
        # 设置编辑模式 不允许编辑 编辑通过textEdit进行
        self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        # 设置选择行 
        self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        # 禁止多选
        self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)

        # 安装事件过滤器 拦截和处理其他对象发送给该对象的事件。
        self.installEventFilter(self)
        # 开启鼠标跟踪 不需要开启
        # self.setMouseTracking(True)
    def _setValueType(self, valueType:str='text'):
        self._initValueTypeWidget(valueType)
    def _initValueTypeWidget(self, curType:str='text'):
        self.__valueWidget = self.TYPES.get(curType, CustomCellStr)
    # 初始化表头
    def _initHeaders(self):
        self.setColumnCount(2)
        self.setHorizontalHeaderLabels(['数据', '操作'])
        # 其中操作列固定宽度 为 80 数据列宽度自适应整个界面大小
        self.horizontalHeader().setSectionResizeMode(self.col_value, QtWidgets.QHeaderView.Stretch)
        self.horizontalHeader().setSectionResizeMode(self.col_button, QtWidgets.QHeaderView.Fixed)
        # 设置操作列宽度
        self.setColumnWidth(self.col_button, 150)
        self.horizontalHeader().setHighlightSections(False)
    # 移除指定行
    def _removeRow(self, row=None):
        count = self.rowCount()
        if count != 0:
            curRow = self.currentRow()
            if row != None:
                curRow = row
            self.removeRow(curRow)
        else:
            return '没有可以删除的数据'
    # 添加行
    def _addRow(self, rowIndex=None):
        curRow = self.rowCount()
        if rowIndex != None:
            curRow = rowIndex
        self.insertRow(curRow)
        widgetToolboxs = CustomCellToolbar(self)
        valueWidget =  self.__valueWidget(self) 
        self.setCellWidget(curRow, self.col_value, valueWidget)
        self.setCellWidget(curRow, self.col_button, widgetToolboxs)
        self.setRowHeight(curRow, 40)
        # 每次添加的时候默认添加一个焦点到 文本编辑框上
        return curRow
    # 设置文本框焦点
    def _setTextFocus(self, row:int=0):
        cellWidget = self.cellWidget(row, self.col_value)
        cellWidget.widget.setFocus()
    # 设置当前行
    def _setCurRow(self, row:int=0):
        self.selectRow(row)

    # 更新行焦点，文本框焦点
    def _updateAllFocus(self, rowIndex):
        self._setCurRow(rowIndex)
        self._setTextFocus(rowIndex)
    # 通过创建的cellWidget 反向查找行索引
    def _findRowByCellWidget(self, cellWidgetToolbox):
        for row in range(self.rowCount()):
            if self.cellWidget(row, self.col_button) == cellWidgetToolbox:
                return row
        return -1
    # 点击了行中的删除按钮
    def _delRowHandle(self, cellWidgetToolbox, *args, **kwargs):
        row = self._findRowByCellWidget(cellWidgetToolbox)
        if row != -1:
            self._setCurRow(row)
            self._removeRow()
        else:
            print('未知错误, 删除失败 !')
    def _addRowHandle(self, cellWidgetToolbox, *args, **kwargs):
        row = self._findRowByCellWidget(cellWidgetToolbox)
        if row != -1:
            rowIndex = self._addRow(rowIndex=row+1)
        else:
            rowIndex = self._addRow()
        self._updateAllFocus(rowIndex)
    # 初始化数据
    def _initData(self, data:list=[]):
        self._clear()
        # 如果数据行数大于当前行数 需要设置新行 同时需要设置widgetItem 
        for row in range(len(data)):
            rowIndex = self._addRow()
            valueWidget = self.cellWidget(rowIndex, self.col_value)
            valueWidget._set(data[row])
        # 更新按钮状态

    def _clear(self):
        num_rows = self.rowCount()
        if num_rows > 0:
            for i in range(num_rows):
                # 移除该行的所有单元格和数据
                for column in range(self.columnCount()):
                    cell_widget = self.cellWidget(i, column)
                    if cell_widget is not None:
                        cell_widget.deleteLater()
        self.setRowCount(0) # 
    # 获取数据 注意空行的数据排除
    def _get(self):
        data = []
        # 范围应该是 0 到 rowCount - 1  因为从0开始
        for row in range(0, self.rowCount()):
            valueWidget = self.cellWidget(row, self.col_value)
            value = valueWidget._get()
            if value != '' and value != None:
                data.append(value)
        return data
    
    def _getAll(self):
        data = []
        # 范围应该是 0 到 rowCount - 1  因为从0开始
        for row in range(self.rowCount()):
            value = self.cellWidget(row, self.col_value)._get()
            if value == '' or value == None:
                value = ''
            data.append(value)

        return data
    # 设置显示数据
    def _set(self, data:list=[]):
        self._initData(data)
    # 移动数据
    def _moveRow(self, fromRow:int, toRow:int):
        # 获取数据
        data = self._getAll()
        # 移动数据
        data.insert(toRow, data.pop(fromRow))
        # 设置数据
        self._initData(data)

    # 向上移动当前行
    def _moveUp(self):
        curRow = self.currentRow()
        if curRow > 0:
            self._moveRow(curRow, curRow - 1)
        else:
            return '已经是最顶部了'
    # 向上移动到最顶部
    def _moveTop(self):
        curRow = self.currentRow()
        if curRow > 0:
            self._moveRow(curRow, 0)
        else:
            return '已经是最顶部了'
    # 向下移动当前行
    def _moveDown(self):
        curRow = self.currentRow()
        # 需要获取最后一行 如果下一行是最后一行则应该创建新的行
        if curRow == (self.rowCount() - 1):
            return '已经是最底部了'
        self._moveRow(curRow, curRow + 1)
        
    # 向下移动到最底部
    def _moveBottom(self):
        curRow = self.currentRow()
        # 需要获取最后一行 如果下一行是最后一行则应该创建新的行
        if curRow == (self.rowCount() - 1):
            return '已经是最底部了'
        self._moveRow(curRow, self.rowCount() - 1)

    